package com.core.sms.service;

import com.common.utils.Constants;
import com.common.utils.StringUtils;
import com.common.exception.BusinessException;
import com.common.redis.RedisCache;
import com.common.utils.Utils;
import com.core.sms.common.AbstractSms;
import com.core.sms.model.SmsMobileCode;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.HashSet;
import java.util.concurrent.TimeUnit;

@Service
public class SmsServer {

    public int getExpireTime() {
        return expireTime;
    }

    public int getInterval() {
        return interval;
    }

    @Value("${sms.enable:false}")
    private boolean enable;
    /**验证码有效时间 默认5分钟*/
    @Value("${sms.expireTime:5}")
    private int expireTime;
    /**短信服务商 0阿里云 1天翼云*/
    @Value("${sms.smsType:1}")
    private int smsType;
    /**短信发送间隔 默认30s*/
    @Value("${sms.interval:30}")
    private int interval;

    //阿里云配置信息
    /** 短信签名 */
    @Value("${sms.sign-name:睿网智联}")
    private String smsSignName;
    /**短信模板*/
    @Value("${sms.templateCode:SMS_209470873}")
    /**账号ID*/
    private String smsTemplateCode;
    @Value("${sms.access-key-id:LTAI4Fg4upKmAfACrrCq9QpN}")
    private String accessKeyId;
    /**密钥*/
    @Value("${sms.access-key-secret:fDrYhIRTk5S24mTuAPLYCPvZUWg2br}")
    private String accessKeySecret;

    //天翼云配置信息
    /**服务地址*/
    @Value("${sms.ip:14.29.202.151}")
    private String ip;
    /**端口*/
    @Value("${sms.port:8888}")
    private String port;
    /**企业编号*/
    @Value("${sms.enterpriseNo:GD10A332947}")
    private String enterpriseNo;
    /**账号*/
    @Value("${sms.account:02001331305}")
    private String account;
    /**密钥*/
    @Value("${sms.signKey:756F315A2A83296A}")
    private String signKey;

    @Resource
    private RedisCache redisCache;

    AbstractSms abstractSms;

    @PostConstruct
    public void init() throws Exception {
        if (enable) {
            if (smsType == 0) {
                abstractSms = new AliAbstractSms(accessKeyId, accessKeySecret, smsSignName, smsTemplateCode);
            }else if(smsType == 1){
                abstractSms = new Ecloud(ip,port,enterpriseNo,account,signKey);
            }else{
                throw new Exception("选择出错短信服务商，请检查配置文件");
            }

        }
    }

    /**
     * @Author: zql
     * @Description: 发送验证码
     * @param mobile 手机号
     * @Data: 17:01 2021/7/23
     */
    public void senCode(String mobile) throws BusinessException {
        String code="1234";
        if(enable) {
            code = Utils.vCode();
            abstractSms.senCode(mobile,code);
        }
        createMobileCode(mobile, code);
    }
    /**
     * @Author: zql
     * @Description: 发送验证码 为了验证过滤短信
     * @param mobile 手机号
     * @Data: 17:01 2021/7/23
     */
    public void senCodeRemove(String mobile,String code) throws BusinessException {
        //String code="1234";
        createMobileCode(mobile, code);
    }


    /**
     * @Author: zql
     * @Description: 使用redis缓存记录手机验证码
     * @param mobile 手机号
     * @param smsCode 验证码
     * @Data: 8:59 2021/7/13
     */
    private void createMobileCode(String mobile, String smsCode) {
        String key = getSmsCodeKey(mobile);
        SmsMobileCode smsMobileCode = redisCache.getCacheObject(key);
        if (StringUtils.isNull(smsMobileCode)) {
            smsMobileCode = new SmsMobileCode();
            smsMobileCode.setMobile(mobile);
            smsMobileCode.setSmsCodes(new HashSet<>());
        }
        smsMobileCode.getSmsCodes().add(smsCode);
        refreshSms(smsMobileCode);
    }

    /**
     * @Author: zql
     * @Description: 刷新手机号的验证码有效期
     * @param smsMobileCode 手机验证码存储的对象
     * @Data: 9:02 2021/7/13
     */
    private void refreshSms(SmsMobileCode smsMobileCode) {
        String key = getSmsCodeKey(smsMobileCode.getMobile());
        smsMobileCode.setLoginTime(System.currentTimeMillis());
        smsMobileCode.setExpireTime(smsMobileCode.getLoginTime() + expireTime * Constants.MINUTE_MILLIS);
        redisCache.setCacheObject(key, smsMobileCode, expireTime, TimeUnit.MINUTES);
    }



    /**
     * @Author: zql
     * @Description: 校验验证码是否正确
     * @param mobile 手机号
     * @param mobileCode 需校验的验证码
     * @Data: 9:05 2021/7/13
     */
    public boolean check(String mobile, String mobileCode) {
        String key = getSmsCodeKey(mobile);
        SmsMobileCode smsMobileCode = redisCache.getCacheObject(key);
        if (smsMobileCode == null || !smsMobileCode.getSmsCodes().contains(mobileCode)) {
            return false;
        }
        redisCache.deleteObject(key);
        return true;
    }

    /**
     * @Author: zql
     * @Description: 给短信服务存储的验证码key加上前缀关键字
     * @param mobile 手机号
     * @Data: 9:06 2021/7/13
     */
    private String getSmsCodeKey(String mobile) {
        StringBuffer str = new StringBuffer();
        str.append(Constants.SMS_CODE_KEY).append(mobile);
        return str.toString();
    }




    /**
     * @Author: zql
     * @Description: 检查剩余有效时间
     * @param mobile 手机号
     * @Data: 9:02 2021/7/13
     */
    public long countDown(String mobile) {
        String key = getSmsCodeKey(mobile);
        SmsMobileCode smsMobileCode = redisCache.getCacheObject(key);
        if (smsMobileCode == null) {
            return 0;
        }
        //过期时间
        long expireTime = smsMobileCode.getExpireTime();
        //当前时间
        long currentTime = System.currentTimeMillis();
        //剩余时间
        long effectiveTime = (expireTime - currentTime);
        //把剩余时间转换成秒
        effectiveTime = effectiveTime / Constants.SECOND_MILLIS;
        //距离上次发送验证码已经经过的时间（秒）
        long second = this.expireTime * Constants.MINUTE_MILLIS / Constants.SECOND_MILLIS - effectiveTime;
        //距离下次发送剩余时间
        long countDown = interval - second;
        return countDown < 0 ? 0 : countDown;
    }
}
